﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;

namespace ControleEstoque.Entidades
{
	public abstract class Reader
	{
		#region Static

		public static Reader CreateReader()
		{
			string currentReader = ConfigurationSettings.AppSettings["CurrentReader"];

			Type readerType = Type.GetType(currentReader);

			ConstructorInfo readerConstructor = readerType.GetConstructor(new Type[0]);

			return readerConstructor.Invoke(new object[0]) as Reader;
		}

		#endregion Static

		#region Fields

		bool _connected;

		#endregion Fields

		#region Properties

		public bool Connected
		{
			get { return _connected; }
			protected set { _connected = value; }
		}

		#endregion Properties

		#region Abstract

		public virtual bool Connect(string address, int port)
		{
			this.Connected = true;
			return true;
		}
		public virtual bool Disconnect()
		{
			this.Connected = false;
			return true;
		}
		public virtual bool SetReadLoop(byte antenna)
		{
			return true;
		}

		/// <summary>
		/// Read an ECPN from the RFID Reader hardware.
		/// </summary>
		/// <returns>The read ECPN.</returns>
		public abstract string Read();

		/// <summary>
		/// Read a number of EPCNs according to received parameters from the specified antenna
		/// </summary>
		/// <param name="num">The number of ECPNs to read.</param>
		/// <param name="antenna">The antena from where the ECPNs will be read.</param>
		/// <returns>An array fulfilled with the read ECPNs.</returns>
		public abstract string[] Read(int num, byte antenna);

		public abstract bool Write(string epcn);

		public abstract bool Write(string epcn, string passwd);
		//public virtual string ReadData(string tid, byte startaddr, byte datalength, byte antenna)
		//{
		//    return null;
		//}
		//public virtual bool WriteData(string tid, byte startaddr, byte antenna, string sdata)
		//{
		//    return false;
		//}
		public virtual bool PowerAmplifier(string onoff)
		{
			return PowerAmplifier(onoff, 1);
		}
		public virtual bool PowerAmplifier(string onoff, byte antenna)
		{
			return true;
		}

		#endregion Abstract

		#region Static

		public static void Checksum(byte[] data, int tamanho)
		{
			int i, cont = 0;
			int x, y, crcValue = 0;
			int aux = tamanho;

			while ((aux--) != 0)
			{
				for (i = 0x80; i != 0; i >>= 1)
				{
					crcValue = (crcValue & 0x8000) != 0 ? (crcValue << 1) ^ 0x8005 : crcValue << 1;
					if ((data[cont] & i) != 0)
						crcValue ^= 0x8005;
				}
				cont++;
			}
			crcValue &= 0xFFFF;
			y = crcValue & 0x00FF;
			x = crcValue & 0xFF00;
			x >>= 8;
			data[tamanho] = (byte)x;
			data[tamanho + 1] = (byte)y;
		}

		#endregion Static

	}
}
